package com.xianyuwangyou.taizhangdengji

import android.content.Context
import android.os.Build
import android.os.Environment
import android.util.Log
import com.thegrizzlylabs.sardineandroid.Sardine
import com.thegrizzlylabs.sardineandroid.impl.OkHttpSardine
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.ByteArrayOutputStream

/**
 * WebDAV同步管理类
 * 负责处理与WebDAV服务器的数据同步操作
 */
class WebDAVSyncManager private constructor() {
    private val TAG = "WebDAVSyncManager"
    
    companion object {
        @Volatile
        private var INSTANCE: WebDAVSyncManager? = null

        fun getInstance(): WebDAVSyncManager {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: WebDAVSyncManager().also { INSTANCE = it }
            }
        }
    }
    
    /**
     * WebDAV配置数据类
     */
    data class WebDAVConfig(
        val serverUrl: String,
        val username: String,
        val password: String,
        val remotePath: String = "/"
    )
    
    /**
     * 同步结果回调接口
     */
    interface SyncCallback {
        fun onSuccess(message: String)
        fun onError(error: String)
    }
    
    /**
     * 从应用外部存储获取数据文件路径
     */
    private fun getExternalDataFile(context: Context): File {
        // 使用现代方式获取外部存储目录，适配Android 10及以上版本
        val externalDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 在Android 10及以上版本中，使用外部公共目录确保数据持久性
            val externalPublicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
            File(externalPublicDir, "TaizhangDengji")
        } else {
            // Android 9及以下版本
            File(Environment.getExternalStorageDirectory(), "TaizhangDengji")
        }
        
        if (!externalDir.exists()) {
            externalDir.mkdirs()
        }
        return File(externalDir, "data.json")
    }
    
    /**
     * 从应用外部存储获取配置文件路径
     */
    private fun getExternalConfigFile(context: Context): File {
        // 使用现代方式获取外部存储目录，适配Android 10及以上版本
        val externalDir = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // 在Android 10及以上版本中，使用外部公共目录确保数据持久性
            val externalPublicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
            File(externalPublicDir, "TaizhangDengji")
        } else {
            // Android 9及以下版本
            File(Environment.getExternalStorageDirectory(), "TaizhangDengji")
        }
        
        if (!externalDir.exists()) {
            externalDir.mkdirs()
        }
        return File(externalDir, "config.json")
    }
    
    /**
     * 将FileInputStream转换为ByteArray
     */
    private fun readFileBytes(file: File): ByteArray {
        val inputStream = FileInputStream(file)
        val outputStream = ByteArrayOutputStream()
        val buffer = ByteArray(1024)
        var bytesRead: Int
        
        while (inputStream.read(buffer).also { bytesRead = it } != -1) {
            outputStream.write(buffer, 0, bytesRead)
        }
        
        inputStream.close()
        return outputStream.toByteArray()
    }
    
    /**
     * 上传文件到WebDAV服务器
     */
    fun uploadToWebDAV(context: Context, config: WebDAVConfig, callback: SyncCallback) {
        Thread {
            try {
                val sardine: Sardine = OkHttpSardine()
                sardine.setCredentials(config.username, config.password)
                
                // 获取本地数据文件
                val dataFile = getExternalDataFile(context)
                val configFile = getExternalConfigFile(context)
                
                if (!dataFile.exists() && !configFile.exists()) {
                    callback.onError("本地没有找到需要同步的数据文件")
                    return@Thread
                }
                
                // 确保远程路径以/结尾
                val remotePath = if (config.remotePath.endsWith("/")) config.remotePath else "${config.remotePath}/"
                
                // 确保远程目录存在
                val serverUrl = if (config.serverUrl.endsWith("/")) config.serverUrl else "${config.serverUrl}/"
                val davUrl = "${serverUrl}remote.php/dav/files/${config.username}${remotePath}"
                
                // 上传数据文件
                if (dataFile.exists()) {
                    val dataBytes = readFileBytes(dataFile)
                    sardine.put("${davUrl}data.json", dataBytes)
                }
                
                // 上传配置文件
                if (configFile.exists()) {
                    val configBytes = readFileBytes(configFile)
                    sardine.put("${davUrl}config.json", configBytes)
                }
                
                callback.onSuccess("数据已成功上传到WebDAV服务器")
            } catch (e: Exception) {
                Log.e(TAG, "上传到WebDAV失败", e)
                callback.onError("上传失败: ${e.message}")
            }
        }.start()
    }
    
    /**
     * 从WebDAV服务器下载文件
     */
    fun downloadFromWebDAV(context: Context, config: WebDAVConfig, callback: SyncCallback) {
        Thread {
            try {
                val sardine: Sardine = OkHttpSardine()
                sardine.setCredentials(config.username, config.password)
                
                // 确保远程路径以/结尾
                val remotePath = if (config.remotePath.endsWith("/")) config.remotePath else "${config.remotePath}/"
                
                // 确保远程目录存在
                val serverUrl = if (config.serverUrl.endsWith("/")) config.serverUrl else "${config.serverUrl}/"
                val davUrl = "${serverUrl}remote.php/dav/files/${config.username}${remotePath}"
                
                // 获取本地数据文件路径
                val dataFile = getExternalDataFile(context)
                val configFile = getExternalConfigFile(context)
                
                // 下载数据文件
                try {
                    val dataInputStream = sardine.get("${davUrl}data.json")
                    val dataOutputStream = FileOutputStream(dataFile)
                    dataInputStream.copyTo(dataOutputStream)
                    dataInputStream.close()
                    dataOutputStream.close()
                } catch (e: Exception) {
                    Log.w(TAG, "下载data.json失败", e)
                }
                
                // 下载配置文件
                try {
                    val configInputStream = sardine.get("${davUrl}config.json")
                    val configOutputStream = FileOutputStream(configFile)
                    configInputStream.copyTo(configOutputStream)
                    configInputStream.close()
                    configOutputStream.close()
                } catch (e: Exception) {
                    Log.w(TAG, "下载config.json失败", e)
                }
                
                callback.onSuccess("数据已成功从WebDAV服务器下载")
            } catch (e: Exception) {
                Log.e(TAG, "从WebDAV下载失败", e)
                callback.onError("下载失败: ${e.message}")
            }
        }.start()
    }
    
    /**
     * 同步数据到WebDAV服务器（先上传后下载）
     */
    fun syncWithWebDAV(context: Context, config: WebDAVConfig, callback: SyncCallback) {
        // 先上传本地数据
        uploadToWebDAV(context, config, object : SyncCallback {
            override fun onSuccess(message: String) {
                // 上传成功后再下载服务器数据
                downloadFromWebDAV(context, config, object : SyncCallback {
                    override fun onSuccess(message: String) {
                        callback.onSuccess("同步完成: $message")
                    }
                    
                    override fun onError(error: String) {
                        callback.onError("下载失败: $error")
                    }
                })
            }
            
            override fun onError(error: String) {
                callback.onError("上传失败: $error")
            }
        })
    }
}